perm filename FILLER.SAI[PUB,TES] blob sn#073667 filedate 1974-03-15 generic text, type C, neo UTF8
COMMENT ⊗   VALID 00013 PAGES
C REC  PAGE   DESCRIPTION
C00001 00001
C00003 00002	ENTRY TEXTLINE 
C00005 00003	COMMENT			T H E   L I N E   F I L L E R
C00010 00004	INTERNAL STRING SIMPLE PROCEDURE LABELREF(INTEGER USYMB, LEN) 
C00013 00005	SIMPLE PROCEDURE OKSP(BOOLEAN EVEN_BEFORE_LMARG) 
C00019 00006	INTEGER XLBFAKE   RKJ: FOR FORWARD REFERENCES IN BOUNDED ITEMS 
C00024 00007	INTERNAL RECURSIVE PROCEDURE DBREAK 
C00029 00008	SIMPLE PROCEDURE UNSCRIPT(INTEGER ARROW) 
C00033 00009	RECURSIVE PROCEDURE PROCESS 
C00038 00010	ie 7 ... \  IF ON THEN	BEGIN "NEXT TAB"
C00042 00011	ie 15 ... hyphen  IF MIDWORD AND FILL AND ON AND ¬SUPERSUB THEN
C00046 00012	INTERNAL RECURSIVE BOOLEAN PROCEDURE TEXTLINE 
C00050 00013	END "INNER BLOCK" 
C00051 ENDMK
C⊗;
ENTRY TEXTLINE ;
BEGIN "FILLER"

DEFINE TERNAL = "EXTERNAL" , PRELOAD = "COMMENT" ;
REQUIRE "PUBDFS.SAI" SOURCE_FILE ;
REQUIRE "PUBMAI.SAI" SOURCE_FILE ;
BEGIN "INNER BLOCK"
REQUIRE "PUBINR.SAI" SOURCE_FILE ;
REQUIRE "PUBPRO.SAI" SOURCE_FILE ;

comment, the following EXTERNAL SIMPLE PROCEDUREs are INTERNAL in PARSER.SAI ;

EXTERNAL STRING SIMPLE PROCEDURE RD(INTEGER BRKTBL) ;

EXTERNAL RECURSIVE STRING PROCEDURE PASS ;

EXTERNAL RECURSIVE STRING PROCEDURE E(STRING DEFAULT, STOPWORD) ;

EXTERNAL STRING SIMPLE PROCEDURE VEVAL ;

EXTERNAL STRING SIMPLE PROCEDURE EVALV(STRING THISWD ; INTEGER IX, TYP) ;

EXTERNAL SIMPLE PROCEDURE SWITCHFONT(INTEGER WHICH) ; TES 11/15/73 ;

FORWARD RECURSIVE PROCEDURE BOUND(INTEGER KIND) ;
COMMENT			T H E   L I N E   F I L L E R

             These routines build a first pass output line  in  string  OWL
        and then call the line placer (PLACELINE()) to place it in an area.
        OWL is kept lengthy enough to hold  any  first  pass  output  line.
        That  way,  a  line  can be constructed by IDPB'ing (with APPEND())
        inside OWL instead of by numerous concatenations.
             Characters  in OWL[1 TO OAKS] belong to the current line being
        built.  However, some of these characters describe FONT changes  or
        forward  label  references and others mark word breaks or CR to the
        left margin for superimposing.  Thus,  the  line  reaches  only  to
        column  POSN  (relative  to the left edge of the area), and FAKE of
        these columns are not occupied but are only allocated  for  forward
        references.   Furthermore, in FILL mode, the last permissible point
        after which the line can be broken by a  CrLf  is  marked  by  four
        variables:  BRKPT, BRKPOSN, BRKSPCS, and BRKFAKE, which contain the
        values of OAKS, POSN, and FAKE at that point,  and  the  number  of
        delible  spaces right after that point.  Though there is normally a
        WDBRK character at the breakpoint, there may be none if it  is  the
        first breakpoint on the line or if it was caused by a hyphen.
             TEXTLINE sets up the input stream for processing  by  PROCESS.
        PROCESS  scans  it  up  to a {, cr, or altmode, obeying all control
        characters and EMITting all regular characters. EMIT  calls  APPEND
        after  checking  for  line  overflow,  etc.  Spaces  are  PROCESSed
        differently -- instead of calling EMIT to APPEND them  immediately,
        EMSPACES is called, which just counts up spaces in SPCS and handles
        COMPACTion and punctuation problems.  Thus, when EMIT is called, it
        must append SPCS spaces before appending its argument. ;

SIMPLE PROCEDURE APPEND(STRING CHARS) ;
IF ON THEN
BEGIN "APPEND"
STRING D ; INTEGER CCT, BALANCE ;
DEFINE SRC="'15", COUNT="'14", DEST="'13", CHAR="'11" ;
CCT ← LENGTH(CHARS) ;
IF (BALANCE ← LENGTH(OWL) - (OAKS+CCT)) < 0 THEN
	OWL ← OWL & SPS((1-BALANCE)*2) ;
IF CCT > 0 THEN
	BEGIN
	LABEL IUD ; COMMENT DEPOSIT LOOP ;
	D ← OWL[OAKS+1 FOR 1] ;
	START_CODE "APPD"
	MOVE SRC, CHARS ;
	HRRZ COUNT, CCT ;
	ADDM COUNT, OAKS ;
	MOVE DEST, D ;
IUD:	ILDB CHAR, SRC ;
	IDPB CHAR, DEST ;
	SOJG COUNT, IUD ;
	END "APPD"
	END ;
END "APPEND" ;
INTERNAL STRING SIMPLE PROCEDURE LABELREF(INTEGER USYMB, LEN) ;
IF ¬ON THEN RETURN(NULL) ELSE
BEGIN "LABELREF"
INTEGER PTR, PLIGHT, WASSYMB ; STRING S ;
IF NULSTR(THISWD) THEN ie, Generated Label for {PAGE}. USYMB=0.;
	PTR ← (PLBL ← PUTI(1, PLBL)) LOR TWO(14)   ie Add to Linked List ;
ELSE IF BYTEWD ← NUMBER[ PTR ← SYMNUM(THISWD & ":") ] THEN
	BEGIN "KNOWN LABEL"
	CASE (PLIGHT ← LDB(PLIGHTWD(BYTEWD))) MOD 3 OF
		BEGIN COMMENT BY PLIGHT ;
		ie 0 or 3 ... Page Label still Uncertain ; WASSYMB ← SYMPAGE ;
		ie 1 ... Referenced but not defined ; WASSYMB ← LDB(IXWD(BYTEWD)) ;
		ie 2 ... Defined and Certain ;
			BEGIN
			BREAKSET(LOCAL_TABLE,ALTMODE,"IS");
			BREAKSET(LOCAL_TABLE,NULL,"O");
			S ← STBL[LDB(IXWD(BYTEWD))] ;
			RETURN (SCAN(S,LOCAL_TABLE,DUMMY));
			END;
		END ; COMMENT BY PLIGHT ;
	IF USYMB AND LDB(IXN(USYMB)) ≠ LDB(IXN(WASSYMB)) THEN
		BEGIN "DIFFERENT UNIT"
		IF WASSYMB THEN WARN("X-REF ERROR","Label "&SYM[PTR]&
			" was cross-referenced as a "&SYM[WASSYMB]&
			" earlier, but now as a "&SYM[USYMB]) ;
		IF PLIGHT = 1 THEN NUMBER[PTR] ← 1 ROT -2 LOR USYMB ;
		END "DIFFERENT UNIT" ;
	END "KNOWN LABEL"
ELSE NUMBER[PTR] ← 1 ROT -2 LOR USYMB ;
RETURN(RUBOUT & CVS(LEN) & VT & CVS(PTR) & VT) ;
END "LABELREF" ;

SIMPLE PROCEDURE PICKFONT(INTEGER F) ; TES 11/15/73 ;
	APPEND(FONTCHAR&"F"&(IF F<10 THEN (F+"0") ELSE (F+("A"-10))));
SIMPLE PROCEDURE OKSP(BOOLEAN EVEN_BEFORE_LMARG) ;
IF LASTWDBRK ≠ OAKS AND ON AND
	JUSTIFY AND (POSN<MAXIM OR XCRIBL) AND (EVEN_BEFORE_LMARG OR POSN > 0 MAX INDENT) THEN
		BEGIN  APPEND(WDBRK) ;  LASTWDBRK ← OAKS ; END ;

SIMPLE PROCEDURE OKCR(BOOLEAN EVEN_IN_SUPERSUBSCRIPT) ;
IF BRKPT≠OAKS AND ON AND (SUPERSUB=0 OR EVEN_IN_SUPERSUBSCRIPT) THEN
	BEGIN
	BRKPT ← OAKS ;  BRKPOSN ← POSN ;  BRKFAKE ← FAKE ;  BRKPLBL ← PLBL ;  BRKSPCS ← 0 ;
	BRKFONT ← THISFONT ; TES 11/16/73 ;
	BRKXPOSN ← XPOSN - FSHORT ;
	IF SUPERSUB THEN RETURN ;
	BRKABX ← BRKABX MAX ABOVEX ; BRKBLX ← BRKBLX MIN BELOWX ; ABOVEX←BELOWX←0 ;
	END "OKCR" ;

INTERNAL INTEGER SIMPLE PROCEDURE XLENGTH(STRING CHARS);
BEGIN "XL"
INTEGER COUNT;
IF NOT XCRIBL THEN RETURN(0); COMMENT IF NOT IN XCRIBL MODE THEN WE DON'T NEED THIS VALUE;
COUNT←0;
WHILE FULSTR(CHARS) DO
COUNT ← COUNT + CW[LOP(CHARS)];
RETURN (COUNT);
END;

INTEGER SIMPLE PROCEDURE XSPLEN(INTEGER N);
	RETURN(N * CW[SP]);

RECURSIVE PROCEDURE EMIT(STRING CHARS) ;
IF ON THEN
BEGIN
INTEGER NCHARS, EXCHARS, WASBRC ;  STRING EXCESS ;  LABEL ADDIT ; comment Sorry about that ;
INTEGER XCHARL,XSPCL,XEXCHARS; RKJ;
NCHARS ← LENGTH(CHARS) ;
XCHARL ← XLENGTH(CHARS); RKJ;
XSPCL ← XSPLEN(SPCS) ; RKJ;
RKJ: OLD LINE IF POSN + SPCS + NCHARS ≤ MAXIM THEN comment, no overfow ;
IF (IF XCRIBL THEN (XPOSN+XSPCL+XCHARL≤(MAXIM*CHARW)) ELSE (POSN+SPCS+NCHARS≤MAXIM)) THEN comment no overflow;
ADDIT:
	BEGIN
	IF SPCS AND XCRIBL AND (FILL AND ADJUST) AND POSN>INDENT THEN
		BEGIN FSHORT←FSHORT+XSPLEN(1); SPCS←SPCS-1 END;
	IF SPCS THEN BEGIN APPEND(SPS(SPCS)) ; BRKSPCS ← SPCS END ;
	APPEND(CHARS) ;  POSN ← POSN + SPCS + NCHARS ;  SPCS ← 0 ;
	XPOSN ← XPOSN + XSPCL + XCHARL; RKJ;
	END
ELSE IF FILL AND (BRKPT>INDENT OR BRKPOSN>INDENT) THEN comment, go back to a break point ;
	BEGIN
	IF BRKPT=OAKS THEN BEGIN XSPCL ← SPCS ← EXCHARS ← 0 ;  EXCESS ← NULL END
	ELSE BEGIN EXCESS←OWL[BRKPT+1+BRKSPCS TO OAKS]; COPY(EXCESS);
	     XEXCHARS ← XPOSN-FSHORT-BRKXPOSN-BRKSPCS*XSPLEN(1);
	     EXCHARS←POSN-BRKPOSN-BRKSPCS END;
	FAKE ← FAKE - BRKFAKE ;  NOPGPH ← -1 ;  WASBRC ← BRC ;
	OAKS ← BRKPT ; BOUND(3) ; COMMENT ADDED 4/14/72 ;
	PLACELINE(IF OWL[OAKS FOR 1]=WDBRK ∧ LASTWDBRK=OAKS   COMMENT JAN 9 73 ;
		THEN OAKS-1 ELSE OAKS,  BRKPOSN MIN MAXIM, BRKXPOSN,
		BRKFAKE, BRKABX, -BRKBLX, IF FIRST THEN LEADFM ELSE SPREADM-1,
		BRKPLBL, ADJUST, SPREADM) ;
	FSHORT ← NOPGPH ← OAKS ← TABI ← BRKABX ← BRKBLX ← STARPOSN ← AMPPOSN ← LASTWDBRK ← 0 ; BRC←WASBRC;
	IF FIRST THEN	BEGIN
			INDENT ← RESTIM MAX -LMARG ; FIRST ← FALSE ;
			END ;
	IF XCRIBL
	    THEN
		BEGIN
		PICKFONT(BRKFONT) ; BRKFONT ← THISFONT ; TES 11/16/73 ;
		IF (LMARG+INDENT)≠0 THEN APPEND(FONTCHAR&"="&CVSR("CHARW*(LMARG+INDENT)"));
		XPOSN←CHARW*INDENT;
		END
	    ELSE
		BEGIN
		APPEND(SPS(LMARG+INDENT));
		END;
	POSN←INDENT; OKCR(TRUE);
	IF UNDERLINING THEN APPEND(FONTCHAR&"_");
	APPEND(EXCESS);
	POSN←POSN+EXCHARS;  XPOSN←XPOSN+XEXCHARS;
	IF SPCS THEN BEGIN OKSP(FALSE) ;  OKCR(FALSE) END ;
	GO  TO  ADDIT   ;
	END
ELSE IF POSN≤MAXIM THEN comment, About to overflow right edge of area! ;
	BEGIN
	APPEND((SPS(SPCS)&CHARS)[1 TO MAXIM - POSN]) ;
	IF XCRIBL AND FONTFIL[DEFAULTFONT]=0 THEN TES 11/15/73;
		WARN("=", "FONT declaration needed. Start over!")
	ELSE
	WARN("Line too long","Line too long -- characters lost:"&CHARS[MAXIM-POSN+1 TO ∞]&"...") ;
	POSN ← MAXIM+1 ; SPCS ← 0 ;
XPOSN ← XMAXIM + 1; RKJ;
	END ;
MIDWORD ← MIDWORD OR FULSTR(CHARS) ;  PUNC ← FALSE ;
END "EMIT" ;
INTEGER XLBFAKE;   RKJ: FOR FORWARD REFERENCES IN BOUNDED ITEMS ;
RECURSIVE PROCEDURE BOUND(INTEGER KIND) ;
IF ON THEN
BEGIN
INTEGER LB, RB, DEST, FILLIN, XLB, XFILLIN ;
LABEL SLIDEFILL, TABFILL, TABCASE ;  STRING FILLER, BOUNDS ;
STRING SEGMENT ;
COMMENT	KIND	≤ 0 ... ∞X	(The ASCII of X negated)
		= 1 ... ←
		= 2 ... →
		= 3 ... CR or BREAK
		= 4 ... Tab (\ or ∂) ;
IF KIND=3  OR  KIND=4 AND NULSTR(LBF)  THEN SPCS ← 0  ELSE EMIT(NULL) ;
OKCR(TRUE) ; comment added 4/17/72 ;
Comment An earlier BOUND on this line may have set LBK←KIND ;
IF LBK < 3 THEN CASE LBK MAX 0 OF
BEGIN COMMENT BY KIND ;
ie ≤ 0 ... ∞  Only valid if immediately preceding this Bound ;
	IF LBO < OAKS ∨ SPCS THEN
		BEGIN
		WARN("=","∞ needs a right bound") ;
		LBF ← NULL ;
		END ;
ie = 1 ... ←  Center between left bound at POSN=LBP and this TAB to RBOUND, or between margins ;
	BEGIN "CENTER"
	IF KIND=4 THEN BEGIN XLB←XLBP ; LB←LBP ; RB←RBOUND END
		ELSE BEGIN LB←XLB←0 ; RB←RMARG-LMARG END ;
	BOUNDS ← CVSR("(LMARG+RB)*(IF XCRIBL THEN CHARW ELSE 1)") & CVSR("(LMARG+LBP-LB)*(IF XCRIBL THEN CHARW ELSE 1)");
	FILLIN ← ((RB - POSN) - (LBP - LB)) DIV 2 ; COMMENT UPPER BOUND ESTIMATE ;
SLIDEFILL:
	XFILLIN ← XPOSN - XLBP -(FAKE-XLBFAKE) ; COMMENT LENGTH OF PIECE ;
	SEGMENT ← OWL[LBO+1 TO OAKS] ; COPY(SEGMENT) ; OAKS ← LBO ; FILLER ← OLBF ;
TABFILL:
	APPEND(FONTCHAR & "→") ; APPEND(BOUNDS) ;
	IF XCRIBL THEN
		BEGIN
		RKJ ; APPEND(CVSR(XFILLIN)) ;
		TES ; APPEND(CVSR("(FILLIN*CHARW)/XLENGTH(FILLER)")) ;
		END ;
	APPEND(FILLER & ALTMODE) ;
	APPEND(SEGMENT) ; APPEND(FONTCHAR & "←") ;
	POSN ← POSN + (FILLIN MAX 0) ;
	XPOSN ← XPOSN + (XFILLIN MAX 0) ;
	END "CENTER" ;
ie 2 ... → Right flush against TAB to RBOUND or against right margin ;
	BEGIN "RIGHT FLUSH"
	RB ← IF KIND=4 THEN RBOUND ELSE RMARG-LMARG ;
	FILLIN ← RB - POSN ;
	BOUNDS ← CVSR("(LMARG+RB)*(IF XCRIBL THEN CHARW ELSE 1)") & CVSR("(IF XCRIBL THEN (-CHARW*1000) ELSE -1000)") ;
	GO TO SLIDEFILL ;
	END "RIGHT FLUSH" ;
END ; COMMENT BY KIND ;
IF KIND=3 ∧ FULSTR(LBF) THEN BEGIN RBOUND ← RMARG ; GO TO TABCASE END ;
IF  KIND=4 THEN
	BEGIN "TAB"
	IF FULSTR(LBF) THEN
    TABCASE:	BEGIN
		FILLIN ← RBOUND - POSN ; BOUNDS ← CVSR(LMARG+RBOUND) & CVSR(-1000) ;
		FILLER ← LBF ; SEGMENT ← NULL ; KIND ← KIND + 2 ; GO TO TABFILL ;
		END
	ELSE APPEND(FONTCHAR&"="&CVSR("IF XCRIBL THEN CHARW*(RBOUND+LMARG) ELSE RBOUND+LMARG"));
	BRKXPOSN←BRKXPOSN+FSHORT;  FSHORT←0;
	POSN ← RBOUND ;	XPOSN ← RBOUND * CHARW ;
	END "TAB" ;
IF KIND > 4 THEN KIND ← KIND - 2 ; COMMENT CORRECTS `KIND←KIND+2' ABOVE ↑↑↑↑↑↑↑ ;
IF KIND = 4 AND POSN > MAXIM THEN MAXIM ← NMAXIM+LMARG
ELSE IF FILL THEN MAXIM ← IF KIND ≤ 2 THEN NMAXIM ELSE FMAXIM ;
IF KIND = 3 THEN LBP ← LBO ← 0 ELSE
BEGIN
comment Finally, set Left Bound for a subsequent BOUND ;
LBO ← OAKS ;  LBP ← POSN ;  XLBP ← XPOSN ;  LBK ← KIND ;  MIDWORD ← FALSE ;
XLBFAKE ← FAKE ;
CASE ((KIND+1) MAX 0) DIV 2 OF BEGIN LBF←LBF&(-KIND) ; BEGIN OLBF←LBF ; LBF←NULL END ; OLBF←LBF←NULL END ;
END ;
END "BOUND" ;
INTERNAL RECURSIVE PROCEDURE DBREAK ;
IF ON THEN	IF NOPGPH THEN NOPGPH ← -1 ELSE
BEGIN INTEGER STTS ;
NOPGPH ← -1 ;
BOUND(3) ;
IF POSN > INDENT OR VERBATIM THEN
	BEGIN "A PGPH"
	PLACELINE(IF LASTWDBRK=OAKS THEN OAKS-1 ELSE OAKS, POSN MIN MAXIM, MAXIM*CHARW-FSHORT,
		FAKE, ABOVEX MAX BRKABX,
		-(BELOWX MIN BRKBLX),
		IF NOFILL THEN LEADNM ELSE IF FIRST THEN LEADFM ELSE SPREADM-1,
		PLBL, IF XCRIBL AND ADJUST THEN TRUE ELSE JUSTJUST, 0) ;
	FSHORT ← SINCELFM ← 0 ;
	IF ENDCASE=2 THEN BEGIN STTS←STARTS; IF ENDBLOCK THEN WARN("=","Missed END in Response|Footnote");
	STARTS ← STARTS + STTS ; END ;
	END "A PGPH" ;
END "DBREAK" ;

SIMPLE PROCEDURE EMSPACES(INTEGER N) ;
IF ON THEN BEGIN
	   IF SPCS=0 THEN BEGIN OKSP(FALSE) ; OKCR(FALSE) END ; MIDWORD ← FALSE ;
	   SPCS ← IF COMPACT THEN (SPCS+N) MIN (IF PUNC THEN 2 ELSE 1) ELSE SPCS+N ;
	   END "EMSPACES" ;

RECURSIVE PROCEDURE TABTO(INTEGER POSNO) ;
IF ON THEN
IF FULSTR(LBF) TES 11/1/73; AND (IF XCRIBL THEN (POSNO*CHARW ≤ XPOSN) ELSE (POSNO≤POSN))
		THEN WARN("=","Already passed tab column " & CVS(POSNO))
ELSE IF POSNO>NMAXIM+LMARG AND NOT XCRIBL THEN
	WARN("=","No such tab column "&(IF POSNO>TWO(15) THEN NULL ELSE CVS(POSNO)))
ELSE
BEGIN
RBOUND ← POSNO-1 ;
IF TRUE COMMENT NOFILL ; THEN BOUND(4)
ELSE BEGIN
	APPEND(FONTCHAR&"="&CVSR("IF XCRIBL THEN CHARW*(RBOUND+LMARG) ELSE RBOUND+LMARG"));
	POSN←RBOUND;
     END ;
END "TABTO" ;

RECURSIVE BOOLEAN PROCEDURE ATLEAD(INTEGER LEADSPACES) ;
BEGIN
IF FINDINSET(LEADSPACES) AND FULSTR("SSTK[BODY(LLTHIS)]")THEN RESPOND(LLTHIS)
ELSE RETURN(FALSE) ;
RETURN(TRUE) ;
END "ATLEAD" ;
	
BOOLEAN SIMPLE PROCEDURE SIGNA(INTEGER SIGCH1) ;
BEGIN
INTEGER ARG, RIX, ARGS, SEPS ; STRING SEE ;
SEE ← SIGCH1 & INPUTSTR ;
LLSCAN(SIGNALD[SIGCH1], NEXT_RESP, "CVASC(SEE[1 FOR CLUE(LLTHIS)])=SIGNAL(LLTHIS)") ;
IF LLTHIS = 0 THEN RETURN(FALSE) ; RIX ← LLTHIS ; ARGS ← NUMARGS(RIX) ;
INPUTSTR ← INPUTSTR[CLUE(RIX) TO ∞] ;
IF ARGS THEN	BEGIN "SCAN ARGS"
		SEPS ← RESP_SEP(RIX) ; IF LAST + ARGS > SIZE THEN GROWNESTS ;
		FOR ARG ← 1 THRU ARGS DO
			BEGIN "SEPBREAK"
			SETBREAK(LOCAL_TABLE,
				(SEPS LSH ((ARG-ARGS)*7) LAND '177) & CRLF, NULL, "IS") ;
			SEE ← NULL ;
			DO	BEGIN
				SEE ← SEE & RD(LOCAL_TABLE) ;
				IF BRC = CR THEN
					BEGIN
					IF FULSTR("RD(TO_NON_SP)") ∨ BRC≠RCBRAK
						∨ INPUTSTR[2 FOR 1]≠VT THEN DONE ;
					LOPP(INPUTSTR) ; LOPP(INPUTSTR) ; IF FULSTR(SEE) THEN SEE ← SEE & SP ;
					END
				ELSE BRC ← -1 ;
				END UNTIL BRC < 0 ;
			SNEST[LAST + ARG] ← SEE ;
			IF BRC > 0 THEN
				BEGIN
				WARN("=","Missing Signal Separator") ;
				FOR ARG ← ARG+1 THRU ARGS DO SNEST[LAST+ARG] ← NULL ;
				END ;
			END "SEPBREAK" ;
		IF ON THEN LAST ← LAST + ARGS ; COMMENT "IF" JAN 9 1973 ;
		END "SCAN ARGS" ;
RESPOND(RIX) ; RETURN(TRUE) ;
END "SIGNA" ;
SIMPLE PROCEDURE UNSCRIPT(INTEGER ARROW) ;
BEGIN
INTEGER CHR, PN ; BOOLEAN MORE, WILLRIPT ;
IF ARROW = 0 THEN
	BEGIN COMMENT "]" -- find matching "[" ;
	ARROW ← SUPERSUB LAND '177 ;
	AMPPOSN ← AMPPOSN LSH -9 ; COMMENT 3/28/72 ;
	SUPERSUB ← SUPERSUB LSH -9 ;
	END ;
IF POSN ≤ MAXIM OR XCRIBL THEN
	BEGIN
	EMIT(NULL) ;
	IF ARROW ≠ "." THEN
		BEGIN
		APPEND(FONTCHAR & ("↑"+"↓" - ARROW)) ;
		HEIGHT ← HEIGHT - (IF ARROW="↑" THEN 1 ELSE -1) ;
		END ;
	END ;
WILLRIPT ← TRUE ; comment assume that RIPTPOSNS will be updated by SCRIPT if necessary ;
IF LDB(SPCODE(INPUTSTR)) = AMSAND THEN
	BEGIN
	LOPP(INPUTSTR) ;
	MORE ← TRUE ; PN ← RIPTPOSNS LAND '177 - LMARG ; COMMENT 3/28/72: ;
	AMPPOSN ← ((AMPPOSN LSH -9) LSH 9) LOR ((AMPPOSN LAND '177) MAX POSN) ;
	IF PN<POSN THEN BEGIN APPEND(FONTCHAR&"-"&CVSR(POSN-PN)) ; POSN←PN END ;
	IF (CHR ← LDB(SPCODE(INPUTSTR))) = LBRACK THEN
		BEGIN
		SUPERSUB ← SUPERSUB LSH 9 LOR "." ;
		LOPP(INPUTSTR) ; WILLRIPT ← FALSE ; comment not a ript: won't call SCRIPT! ;
		END
	ELSE IF CHR≠UARROW AND CHR≠DARROW THEN BEGIN EMIT(LOP(INPUTSTR)) ; MORE ← FALSE END ;
	END
ELSE MORE ← FALSE ;
IF ¬MORE THEN BEGIN COMMENT 3/28/72: ;
	PN ← (AMPPOSN LAND '177) MAX POSN ; AMPPOSN ← (AMPPOSN LSH -9) LSH 9 ;
	IF PN>POSN THEN BEGIN APPEND(FONTCHAR&"+"&CVSR(PN-POSN)) ; POSN←PN END END ;
IF WILLRIPT THEN RIPTPOSNS ← RIPTPOSNS LSH -9 ;
END "UNSCRIPT" ;

SIMPLE PROCEDURE SCRIPT(INTEGER ARROW) ;
BEGIN
INTEGER CHR ;
CHR ← LOP(INPUTSTR) ;
HEIGHT ← HEIGHT + (IF ARROW="↑" THEN 1 ELSE -1) ;
ABOVEX ← ABOVEX MAX HEIGHT ;  BELOWX ← BELOWX MIN HEIGHT ;
IF POSN ≤ MAXIM OR XCRIBL THEN BEGIN EMIT(NULL) ; APPEND(FONTCHAR&ARROW) ; END ;
RIPTPOSNS ← RIPTPOSNS LSH 9 LOR (POSN+LMARG) ;
IF LDB(SPCODE(CHR))=LBRACK THEN BEGIN SUPERSUB ← SUPERSUB LSH 9 LOR ARROW ;
	AMPPOSN ← AMPPOSN LSH 9  ; COMMENT 3/28/72 ; END
ELSE BEGIN EMIT(CHR) ; UNSCRIPT(ARROW) END ;
END "SCRIPT" ;
RECURSIVE PROCEDURE PROCESS ;
BEGIN
INTEGER N, CHR, F, INSET ;  BOOLEAN PLUS, DONE ;  STRING PIECE ; LABEL ENDERLINE ;
EMPTYTHIS ; INSET ← 0 ;
IF INPUTSTR = VT THEN  IF ¬ON THEN LOPP(INPUTSTR) ELSE
	BEGIN "NEW INPUT LINE"
	LOPP(INPUTSTR) ;
	IF VERBATIM THEN BEGIN END
	ELSE IF INPUTSTR=CR ∧ (N←SIGNALD[CR]) THEN BEGIN LOPP(INPUTSTR) ; RESPOND(N) ; RETURN END
	ELSE IF ATLEAD(INSET ← LENGTH(RD(TO_NON_SP))) THEN INSET←0 ; comment AT NULL , AT <integer> ;
	END "NEW INPUT LINE" ;
IF NOPGPH ∧ ON THEN  ie, First line of paragraph ;
	BEGIN "START PARAGRAPH"
	OAKS←SPCS←TABI←PUNC←MIDWORD←SUPERSUB←ABOVEX←BELOWX←HEIGHT←FAKE←BRKABX←BRKBLX←UNDERLINING←0 ;
	FIRST ← NOFILL ∨ NOPGPH<0 ;  STARPOSN←AMPPOSN←LASTWDBRK←0 ;
	BRKFONT ← THISFONT ; TES 11/16/73 ;
	INDENT ← IF FLUSHL∨VERBATIM∨CENTER∨FLUSHR THEN 0
		ELSE (IF NOFILL OR FIRST THEN FIRSTIM ELSE RESTIM) MAX -LMARG ;
	NOPGPH ← 0 ; LBK ← 3 ; LBF ← NULL ;
	IF XCRIBL
	    THEN
		BEGIN
		PICKFONT(THISFONT) ; TES 11/15/73 ;
		IF (LMARG+INDENT)≠0 THEN APPEND(FONTCHAR&"="&CVSR("CHARW*(LMARG+INDENT)"));
		XPOSN←CHARW*INDENT;
		END
	    ELSE
		BEGIN
		APPEND(SPS(LMARG+INDENT));
		END;
	POSN←INDENT; FSHORT←0; OKCR(TRUE);
	IF FLUSHR THEN BOUND(2) ELSE IF CENTER THEN BOUND(1) ;
	FMAXIM ← (RMARG-RIGHTIM)-LMARG ;
	NMAXIM ← COLWID(IF AREAIXM THEN AREAIXM ELSE IXTEXT) - LMARG ;
	MAXIM ← IF FILL THEN FMAXIM ELSE NMAXIM ;
	IF VERBATIM THEN BEGIN JUSTIFY←FALSE; EMIT(RD(TO_CR_SKIP)); DBREAK ; RETURN END ;
	END "START PARAGRAPH" ;
JUSTIFY ← FILL∧ADJUST ∨ JUSTJUST ; DONE ← FALSE ; IF INSET∧RETAIN∧¬FLUSHL THEN EMSPACES(INSET) ;
DO BEGIN "SCAN TEXT"
IF FULSTR("PIECE ← RD(TEXT_TBL)") THEN EMIT(PIECE) ;
IF BRC≠CR ∧ SIGNALD[BRC] ∧ SIGNA(BRC) THEN BEGIN COMMENT Responded to signal ; END
ELSE CASE CHARTBL[BRC] LAND '77 OF
BEGIN COMMENT BY BRC ;
ie 0	; EMIT(BRC) ;
ie 1 ... CR ;	BEGIN SUPERSUB←HEIGHT←AMPPOSN←RIPTPOSNS←0 ;
		IF FILL ∧ CRSPACE THEN EMSPACES(IF SPCS ∨ ¬POSN THEN 0 ELSE IF PUNC THEN 2 ELSE 1)
		ELSE IF IMPOSE THEN
			BEGIN "SUPERIMPOSE"
			IF (N ← SINCELFM+1) > TWEENLFM THEN DBREAK
			ELSE BEGIN EMIT(NULL); APPEND(CR & SPS(LMARG+(POSN←INDENT))); SINCELFM ← N ;
				TABI←MIDWORD←STARPOSN←FAKE←0 ; LBK←3; LBF←NULL; OKCR(FALSE) END ;
			END "SUPERIMPOSE"
		ELSE DBREAK ;
		DONE ← TRUE ;
		END ;
ie 2 ... Altmode or { ;	DONE ← TRUE ;
ie 3 ... Rubout;IF ON THEN
			BEGIN "LABEL REF"
			N ← CVD(SCAN(INPUTSTR,TO_VT_SKIP,F)) ;
			IF XCRIBL THEN
			    BEGIN
			    EMIT(S←"01234567890123456789012345678901234567890123456789"[1 FOR N]);
			    FAKE←FAKE+XLENGTH(S);
			    END
			 ELSE
			    BEGIN
			    EMIT(SPS(N)); FAKE←FAKE+N;
			    END;
			OAKS←OAKS-N;
			APPEND(VT&SCAN(INPUTSTR, TO_VT_SKIP, F)&ALTMODE) ;
			END "LABEL REF"
		ELSE FOR N ← 1,2 DO SCAN(INPUTSTR, TO_VT_SKIP, F) ;
ie 4 ... α ; IF INPUTSTR≠ALTMODE THEN IF (N←LOP(INPUTSTR))=CR THEN DONE←TRUE
		ELSE BEGIN "CHKXGP"
			IF XCRIBL THEN
			   IF  (F←LDB(SPCODE(N))) = XCMDCHR
				  THEN BEGIN EMIT(N); APPEND(N) END
				  ELSE EMIT(N)
			  ELSE EMIT(N);
		     END "CHKXGP";
ie 5 ... β ; IF FILL THEN OKCR(FALSE) ELSE EMIT(BRC) ;
ie 6 ... # ; EMIT(SP) ;
ie 7 ... \ ; IF ON THEN	BEGIN "NEXT TAB"
			POSN←POSN+SPCS; XPOSN←XPOSN+XSPLEN(SPCS); SPCS←0;
			DO BEGIN TABI←TABI+1; N←TABSORT[TABI] END
			    UNTIL (IF XCRIBL THEN N*CHARW>XPOSN ELSE N>POSN);
			TABTO(N) ; IF N > NMAXIM+LMARG THEN TABI ← TABI - 1 ;
			END "NEXT TAB" ;
ie 8 ... ∂ ;	IF (CHR←INPUTSTR)=CR ∨ CHR=ALTMODE ∨ NULSTR(INPUTSTR) THEN EMIT(BRC)
	ELSE	BEGIN "SPECIFIC TAB"
		SPCS←0 ;
		CHR ← LOP(INPUTSTR) ;
		IF (PLUS ← CHR)="+" ∨ CHR="-" THEN CHR ← LOP(INPUTSTR) ELSE PLUS←0 ;
		IF CHR="(" THEN
			BEGIN
		        PASS ; N ← CVD(E("0",0)) ;
			IF ¬ITSCH(")") THEN WARN("=","Missed ) after ∂(...") ;
			END
		ELSE IF (F←LDB(FAMILY(CHR)))=0 THEN N←
			CVD(EVALV(SYM[N←SYMNUM(CHR)], LDB(IXN(N)), LDB(TYPEN(N))))
		ELSE IF F = DIGQ THEN N ← CHR - 48 comment, Digit ;
		ELSE BEGIN WARN("=","Unintelligible ∂ Construct") ; N ← 0 END ;
		IF PLUS="-" THEN
			BEGIN "BACKSPACE"
			EMIT(NULL) ; STARPOSN ← POSN MAX STARPOSN ;
			IF XCRIBL THEN
					BEGIN
					APPEND(FONTCHAR&'35&LOP(INPUTSTR));
					IF N ≠ 1 THEN
					    WARN("=","Can't backspace more than one!!");
					END
				  ELSE
					BEGIN
					POSN ← POSN-N MAX 0 ;
					APPEND(FONTCHAR&PLUS&CVSR(N)) ;
					END;
			END
		ELSE IF PLUS="+" ∧ NULSTR(LBF) THEN
			BEGIN
			IF N>0 THEN BEGIN APPEND(FONTCHAR&"+"&CVSR(IF XCRIBL THEN N*CHARW ELSE N));
			POSN←POSN+N MIN NMAXIM+LMARG END;
			END
		ELSE TABTO((IF PLUS="*" THEN STARPOSN ELSE
			    IF PLUS="+" THEN POSN+N ELSE N) MIN NMAXIM+LMARG) ;
		END "SPECIFIC TAB" ;
ie 9 ... ← ; IF LBK ≠ 2 THEN BOUND(1) ELSE EMIT(BRC) ;
ie 10 ... → ; IF LBK ≠ 2 THEN BOUND(2) ELSE EMIT(BRC) ;
ie 11 ... ∞ ; IF (N←INPUTSTR)=CR ∨ N=ALTMODE THEN WARN("=","∞ What?")
	      ELSE BOUND(-LOP(INPUTSTR)) ;
ie 12 ... ↑ ; IF ON ∧ (CHR←INPUTSTR)≠CR ∧ CHR≠ALTMODE THEN SCRIPT("↑") ELSE EMIT(BRC) ;
ie 13 ... ↓ ; IF ON THEN IF (CHR←INPUTSTR)=CR ∨ CHR=ALTMODE THEN EMIT(BRC)
		ELSE IF LDB(SPCODE(INPUTSTR))=UNDERBAR THEN
		BEGIN
		LOPP(INPUTSTR) ;  EMIT(NULL) ;
		IF POSN≤MAXIM OR XCRIBL THEN BEGIN IF UNDERLINING=0 THEN APPEND(FONTCHAR&"_"); UNDERLINING←2 END ;
		END
	      ELSE SCRIPT("↓") ;
ie 14 ... ] ; IF SUPERSUB AND ON THEN UNSCRIPT(0)
	      ELSE EMIT(BRC) ;
ie 15 ... hyphen ; IF MIDWORD AND FILL AND ON AND ¬SUPERSUB THEN
			BEGIN
			EMIT("-") ; OKCR(FALSE) ;
			IF INPUTSTR=CR THEN BEGIN LOPP(INPUTSTR); DONE←TRUE END ;
			END
		   ELSE BEGIN N←MIDWORD ; EMIT(BRC) ; MIDWORD ← N END ;
ie 16 ... .!? ; IF MIDWORD∧FILL∧ON∧¬SUPERSUB THEN BEGIN EMIT(BRC) ; PUNC←TRUE END
		ELSE EMIT(BRC) ;
ie 17 ... space ; EMSPACES(1 + LENGTH(RD(TO_NON_SP)) ) ;
ie 18 ... underline ; IF LDB(SPCODE(INPUTSTR))=DARROW AND ON THEN
			BEGIN
			LOPP(INPUTSTR) ;  EMIT(NULL) ;
			IF UNDERLINING THEN
		ENDERLINE:	BEGIN
				UNDERLINING ← 0 ;
				IF POSN≤MAXIM OR XCRIBL THEN APPEND(FONTCHAR&"≡") ;
				END ;
			END
	ELSE	BEGIN
		EMIT(NULL) ;
		IF POSN≤MAXIM OR XCRIBL THEN EMIT(BRC);
			COMMENT POSN< CHANGED TO POSN≤  ON 2/27/73 TES ;
		END ;
ie 19 ... π ;	BEGIN
		IF (CHR ← INPUTSTR) = "g" THEN CHR ← "G" ;
		IF CHR="G" ∨ CHR="." ∨ CHR="∂" ∨ CHR="+" ∨ CHR="-" ∨ CHR="~" THEN
			BEGIN
			EMIT(NULL) ;
			IF ON ∧ (POSN<MAXIM OR XCRIBL) THEN
				BEGIN APPEND(FONTCHAR&"π") ; EMIT(CHR) END ;
			LOPP(INPUTSTR) ;
			END
		ELSE EMIT(BRC) ;
		END ;
ie 20 ... ∪ ; IF ON ∧ UNDERLINING=0 THEN
	BEGIN COMMENT ∪NDERLINE ONE WORD ;
	EMIT(NULL) ; UNDERLINING ← 1 ;
	IF POSN<MAXIM OR XCRIBL THEN APPEND(FONTCHAR & "_") ;
	IF FULSTR("PIECE←RD(ALPHA)") THEN EMIT(PIECE) ;
	GO TO ENDERLINE ;
	END ;
ie 21 ... ∩ ; EMIT(BRC) ; COMMENT CURRENTLY NOT USED ;
ie 22 ... VT ; WARN("=", "`⊃' SEEMS TO BE ON TEXT LINE IN MACRO") ;
ie 23 ... $ ; IF LDB(SPCODE(INPUTSTR))=LBRACK THEN
	BEGIN LOPP(INPUTSTR) ; DONE←TRUE END ELSE BEGIN WARN("=","!!") ;EMIT(BRC) ; END ;
ie 24 ... % ; IF ON THEN
		BEGIN "PERCENT"
		F←LOP(INPUTSTR);
		IF "1"≤F≤"9" THEN F←F-"0"
		ELSE IF "A"≤F≤"Z" THEN F←F-("A"-10)
		ELSE IF "a"≤F≤"z" THEN F←F-("a"-10)
		ELSE IF F="*" THEN F←OLDFONT
		ELSE BEGIN WARN("=","Illegal font `"&F&"'"); F←0 END;
		IF F>0 AND FONTFIL[F]=0 THEN
		    BEGIN
		   IF XCRIBL THEN  TES 11/5/73 ;
		    WARN("=","Unknown font `"&(IF F<10 THEN (F+"0") ELSE (F+("A"-10)))&"'");
		    F←0;
		    END;
		IF F AND XCRIBL THEN
		    BEGIN
		    EMIT(NULL);
		    IF F NEQ THISFONT THEN PICKFONT(F) ;
		    SWITCHFONT(F) ; TES 11/15/73 SUBROUTINIZED ;
		    END;
		END;
ie 25 ... ⊗ ; EMIT(BRC) ; comment PASS 3 control only, no action here ;
ie 26 ... [ ; EMIT(BRC) ; comment just to be safe ;
ie 27 ... & ; EMIT(BRC)   comment just to be safe ;
END ; COMMENT BY BRC ;
END "SCAN TEXT" UNTIL DONE ;
END "PROCESS " ;
INTERNAL RECURSIVE BOOLEAN PROCEDURE TEXTLINE ;
BEGIN
PRELOAD_WITH 6, [8]0, 1, [2]0, 5, 0, 3, [4]4, [6]0, 4, 2, 4, 2, [2]0 ;
OWN INTEGER ARRAY TEXTTYPE[-15:15] ;
BOOLEAN IMITEXT ;  INTEGER USYMB, LEN ;  STRING STR ;
IMITEXT ← TRUE ; comment assume computed text line ;
CASE TEXTTYPE[THISTYPE] OF
BEGIN COMMENT BY TYPE ;
ie 0 ... Invalid ; RETURN(FALSE) ;
ie 1 ... [ ;	BEGIN comment	[Est] Label or [@] rubout gen-label	; PASS ;
		IF ITS(@) THEN BEGIN PASS ; IMITEXT ← FALSE END
		ELSE	BEGIN LEN ← CVD(E("5", 0)) ; COMMENT THANKS RKJ ;
			IF ITSCH("]") THEN PASS ELSE WARN("=","Missed ] after label length") ;
			THISWD ← LABELREF(0, LEN) ; END ;
		END ;
ie 2 ... Unit ; IF THATISID THEN
		BEGIN comment	Unit Label	;
		USYMB ← SYMB ;
		LEN ← IF THISTYPE=PUNITTYPE THEN PATT_CHRS(IX) ELSE CTR_CHRS(IX) ;
		PASS ; THISWD ← LABELREF(USYMB, LEN) ;
		END
	ELSE IF IX=IXPAGE THEN
		BEGIN comment, Generate a label ;
		THISWD ← NULL ;
		THISWD ← LABELREF(0, IF ITS(PAGE) THEN CTR_CHRS(IXPAGE) ELSE PATT_CHRS(IXPAGE)) ;
		END
	ELSE THISWD ← VEVAL ;
ie 3 ... Constant ;
	BEGIN
	LOPP(THISWD) ;
	IF THATISID ∧ SIMLOOK(CAPITALIZE(STR←SCAN(THISWD,ALPHA,DUMMY)))
		 ∧ (SYMTYPE = UNITTYPE ∨ SYMTYPE = PUNITTYPE) THEN
		BEGIN comment	"Unit.." Label	;
		IF SYMTYPE=PUNITTYPE THEN STR←STR[1 TO ∞-1]; USYMB ← SYMBOL;
		LEN ← IF SYMTYPE=PUNITTYPE THEN PATT_CHRS(SYMIX) ELSE CTR_CHRS(SYMIX) ;
		PASS ; THISWD ← STR & SP & LABELREF(USYMB, LEN) ;
	 	END ;
	END ;
ie 4 ... Variable ;	THISWD ← VEVAL ;
ie 5 ... } etc. ; IF IX comment not } ; THEN RETURN(FALSE) ELSE IMITEXT←FALSE ;
ie 6 ... misc ; IF ITSCH("(") THEN BEGIN PASS; STR←E(NULL,NULL);
		IF ¬ITSCH(")") THEN WARN("=","Parens don't match") ; THISWD←STR END ELSE RETURN(FALSE) ;
END ; COMMENT BY TYPE ;
IF IMITEXT THEN IF NULSTR(THISWD) OR ¬ON THEN ELSE
	BEGIN
	BEGINBLOCK(FALSE, 0, "!NAKED") ;
	SWICH(THISWD&ALTMODE&" END ""!NAKED""", -1, 0) ;
	PROCESS ;
	END
ELSE PROCESS ;
PASS ;
RETURN(TRUE) ;
END "TEXTLINE" ;
END "INNER BLOCK" ;
END "FILLER"